struct Cacher<T,E>
    where 
        T: Fn(E) -> E,
        E: Copy,
{
    query: T,
    value: Option<E>,
    
}
impl<T,E> Cacher<T, E>
    where
        T: Fn(E) -> E,
        E: Copy,
{
    fn new(query: T) -> Cacher<T, E> {
        Cacher {
            query,
            value: None,
        }
    }
    fn value(&mut self, arg: E) -> E {
        match self.value {
            Some(v) => v,
            None => {
                let v = (self.query)(arg);
                self.value = Some(v);
                v
            }
        }
    }
}

fn main() {
    let mut u = Cacher::new(|u|u);
    let i32_1 = 1;
    let i32_2 = 2;
    let v1 = u.value(1);
    let v2 = u.value(2);
    println!("number1:{i32_1},number2:{i32_2},cacher after value1:{v1}, value2:{v2}");
    let mut s = Cacher::new(|s|s);
    let str1 = "hello".to_string();
    let str2 = "world".to_string();
    let v1 = s.value(&str1);
    let v2 = s.value(&str2);
    println!("str1:{str1},str2:{str2},cacher after value1:{v1}, value2:{v2}");
}

//#[test]
//fn call_with_different_values() {
//    let mut c = Cacher::new(|a| a);
//    let v1 = c.value(1);
//    let v2 = c.value(2);
//    assert_eq!(v2, 1);
//}
